#include "../main.h"

int test(int argc, char **argv)
{
	char ip[24] = "";

	int ret = uci_add("speed", "limit");
	printf("ret=%d \n", ret);

	//uci_show("speed.@limit[0]");
	char cmd[128];
	char value[128];
	int count = 0;
	while (1)
	{
		memset(cmd, 0, sizeof(cmd));
		memset(value, 0, sizeof(value));

		snprintf(cmd, sizeof(cmd), "speed.@limit[%d]", count);
		ret = get_value(cmd, &value);
		if (ret == -1)
			break;

		snprintf(cmd, sizeof(cmd), "speed.@limit[%d].ip", count);
		ret = get_value(cmd, &value);
		if (ret == 1)
			printf("%s=%s \n", cmd, value);

		count++;
	}
}

int uci_show(char *tuple)
{
	struct uci_element *e = NULL;
	struct uci_ptr ptr;
	struct uci_context *ctx = uci_alloc_context();

	if (uci_lookup_ptr(ctx, &ptr, tuple, true) != UCI_OK)
	{
		return 1;
	}

	//	struct uci_element *e;
	const char *cname;
	const char *sname;
	struct uci_section *s = ptr.s;

	cname = s->package->e.name;
	sname = s->e.name;
	printf("%s.%s=%s\n", cname, sname, s->type);
	uci_foreach_element(&s->options, e)
	{
		bool sep = false;
		struct uci_option *o = uci_to_option(e);
		printf("%s.%s.%s=",
			   o->section->package->e.name,
			   o->section->e.name,
			   o->e.name);
		switch (o->type)
		{
		case UCI_TYPE_STRING:
			printf("%s\n", o->v.string);
			break;
		case UCI_TYPE_LIST:
			uci_foreach_element(&o->v.list, e)
			{
				printf("%s%s", "", e->name);
				sep = true;
			}
			printf("\n");
			break;
		default:
			printf("<unknown>\n");
			break;
		}
	}
}

int uci_add(char *config, char *section)
{
	struct uci_package *p = NULL;
	struct uci_section *s = NULL;
	struct uci_context *ctx = uci_alloc_context();
	int ret;

	ret = uci_load(ctx, config, &p);
	if (ret != UCI_OK)
		goto done;

	ret = uci_add_section(ctx, p, section, &s);
	if (ret != UCI_OK)
		goto done;

	ret = uci_save(ctx, p);

	if (s)
		fprintf(stdout, "%s\n", s->e.name);

done:

	ret = uci_commit(ctx, &p, false);

	uci_free_context(ctx);

	return ret;
}

/*
--------------------------------------------------------------------------------
	函数功能 ： UCI 获取参数
	get_value("attack.@attack[0].list", &bwlist)
--------------------------------------------------------------------------------
*/
int get_value(char *cmd, char *value)
{
	struct uci_context *c = uci_alloc_context(); //定义一个UCI上下文的静态变量.
	struct uci_ptr p;
	char *a = strdup(cmd);

	//分离一个uci元组字符串且查找对应元素树
	if ((UCI_OK != uci_lookup_ptr(c, &p, a, true)) || (p.flags == UCI_LOOKUP_DONE) || (p.flags == 5)) // 解决attack.@xxx[0].xxx 获取不到崩溃问题
	{
		//printf("### %s ### %s Not Found !\n", __func__, cmd);
		return -1;
	}

	if (p.target == 3) //解决attack.@xxx[0] 获取到崩溃问题
		return 1;

	//printf("### %s ### p.flags=%d \n", __func__, p.flags);
	memcpy(value, p.o->v.string, strlen(p.o->v.string));
	//printf("### %s ### cmd,%s value:%s \n", __func__, cmd, value);
	uci_free_context(c);
	free(a);

	return 1;
}

/*
--------------------------------------------------------------------------------
	函数功能 ： UCI 获取参数
	get_value("attack.@attack[0].list", &bwlist)
--------------------------------------------------------------------------------
*/
char *get_value_change(char *cmd)
{
	struct uci_context *c = uci_alloc_context(); //定义一个UCI上下文的静态变量.
	struct uci_ptr p;
	char *a = strdup(cmd);

	//分离一个uci元组字符串且查找对应元素树
	if ((UCI_OK != uci_lookup_ptr(c, &p, a, true)) || (p.flags == UCI_LOOKUP_DONE) || (p.flags == 5)) // 解决attack.@xxx[0].xxx 获取不到崩溃问题
	{
		uci_free_context(c);
		free(a);
		return NULL;
	}

	if (p.target == 3) //解决attack.@xxx[0] 获取到崩溃问题
	{
		uci_free_context(c);
		free(a);
		return NULL;
	}

	// memcpy(value, p.o->v.string, strlen(p.o->v.string));
	char *value = NULL;
	value = stringCopy(p.o->v.string, strlen(p.o->v.string));
	uci_free_context(c);
	free(a);
	return value;
}

/* 
--------------------------------------------------------------------------------
	函数功能 ： UCI 设置参数
	memset(cmd, 0, sizeof(cmd));
	snprintf(cmd, sizeof(cmd), "wireless.@wifi-iface[%d].hidden", count);
	set_value(cmd, "1");
--------------------------------------------------------------------------------
*/
int set_value(char *cmd, char *value)
{
	if (NULL == cmd || NULL == value)
	{
		return 0;
	}

	int ret = 0;
	struct uci_ptr ptr;
	char uciOption[128];
	struct uci_context *ctx = uci_alloc_context();

	memset(&ptr, 0, sizeof(ptr));
	memset(uciOption, 0, sizeof(uciOption));
	memcpy(uciOption, cmd, sizeof(uciOption) - 1);

	if (UCI_OK != uci_lookup_ptr(ctx, &ptr, uciOption, true))
	{
		//printf("### %s ### %s Not Found !\n", __func__, cmd);
		return 0;
	}

	ptr.value = value;
	ret = uci_set(ctx, &ptr);

	if (0 == ret)
	{
		ret = uci_commit(ctx, &ptr.p, false);
	}
	uci_unload(ctx, ptr.p);
	uci_free_context(ctx);

	return 1;
}
